#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "MyString.h"
#include"DynamicArray.h"

#define Map_Size 5

// struct DynamicArray
// {   
//     void*  dp;
//     int size;
//     int len;

// };

//player
struct Player
{
    int HP;
    int attack;
    int x;
    int y;
};

struct Monster
{
    MyString name;
    int HP;
    int attack;
    int x;
    int y;
};

struct Treasure
{
    MyString name;
    int value;
    int x;
    int y;
};


void InitPlayer(struct Player *player)
{
    player->HP = 100;
    player->attack = 10;
    player->x = 0;
    player->y = 0;
}

int GetRandNumber(int max)
{
    return rand() % max;
}

struct Monster* CreateMonster(const char *Name,int hp,int Attack)
{
    struct Monster *monster = (struct Monster *)malloc(sizeof(struct Monster));
    if(monster == NULL)
    {
        printf("Monster malloc Error!\n");
        return NULL;
    }
    StringInitialize(&monster->name,Name);
    monster->HP = hp;
    monster->attack = Attack;
    
    monster->x = GetRandNumber(Map_Size);
    monster->y = GetRandNumber(Map_Size);

    return monster;
}

struct Treasure* CreateTreasure(const char *name,int value)
{
    struct Treasure * treasure = (struct Treasure *)malloc(sizeof(struct Treasure));
    if(treasure == NULL)
    {
        printf("Treasure malloc Error!\n");
        return NULL;
    }

    StringInitialize(&treasure->name.string,name);
    treasure->value = value;
    
    treasure->x = GetRandNumber(Map_Size);
    treasure->y = GetRandNumber(Map_Size);

    return treasure;
}

int InitMonsters(struct DynamicArray *monsters)
{
    if(Initialize(monsters)==false)
    {
        return false;
    }
    InsertArray(monsters,CreateMonster("dragon",100,20));
    InsertArray(monsters,CreateMonster("centaur",50,10));
    InsertArray(monsters,CreateMonster("centaur",50,10));
    InsertArray(monsters,CreateMonster("goblin",10,2));
    InsertArray(monsters,CreateMonster("goblin",10,2));
    InsertArray(monsters,CreateMonster("goblin",10,2));
    InsertArray(monsters,CreateMonster("goblin",10,2));
    return true;
}

int InitTreasures(struct DynamicArray *treasures)
{
    if(Initialize(treasures)==false)
    {
        return false;
    }
    InsertArray(treasures,CreateTreasure("baoxiang",500));
    InsertArray(treasures,CreateTreasure("baoxiang",500));
    InsertArray(treasures,CreateTreasure("baoxiang",500));
    InsertArray(treasures,CreateTreasure("money",100));
    InsertArray(treasures,CreateTreasure("money",100));
    InsertArray(treasures,CreateTreasure("medicine",5));
    InsertArray(treasures,CreateTreasure("medicine",5));
    return true;
}

void MakeMove(struct Player *player,int dx,int dy)
{
    player->x+=dx;
    player->y+=dy;
    if(player->x<0)  player->x=0;
    if(player->x>=Map_Size)  player->x=Map_Size-1;
    if(player->y<0)  player->y=0;
    if(player->y>=Map_Size)  player->y=Map_Size-1;
}

int Battle(struct Player *player,struct Monster *monster)
{
    printf("您遭遇到了怪兽%s 血量：%d 攻击力：%d\n",monster->name.string,monster->HP,monster->attack);
    while(1)
    {
        // system("clear");
        printf("请选择你的行动:1.攻击 2.防御 3.逃跑\n");
        printf("请选择:");
        int choice=0;
        scanf("%d",&choice);

        switch(choice)
        {
            case 1:
                printf("你对怪兽造成了 %d 伤害\n",monster->attack);
                printf("怪兽对你进行了还击,造成了 %d 伤害\n",monster->attack);
                player->HP -=monster->attack;
                monster->HP -=player->attack;
                printf("当前怪物的剩余血量:%d\n",monster->HP);
                printf("当前你的剩余血量:%d\n",player->HP);
                break;
            case 2:
                printf("怪兽对你进行了攻击!\n");
                if(GetRandNumber(2)==1)
                {
                    printf("你防御住了!\n");
                }
                else
                {
                    printf("怪兽破开了你的防御,造成了 %d 伤害!\n",monster->attack);
                    player->HP -=monster->attack;
                }
                break;
                // printf("当前怪物的剩余血量:%d\n",monster->HP);
                // printf("当前你的剩余血量:%d\n",player->HP);    
            case 3:
                if(GetRandNumber(2)==1)
                {
                    printf("逃跑成功!\n");
                    return true;
                }
                else
                {
                    printf("逃跑失败,怪兽对你造成了 %d 伤害!\n",monster->attack);
                    player->HP -=monster->attack;
                }
                break;
                // printf("当前怪物的剩余血量:%d\n",monster->HP);
                // printf("当前你的剩余血量:%d\n",player->HP);         
            default:
                break;

        }
        if(player->HP<=0)
        {
            player->HP=0;
            printf("你被怪兽杀死了!\n");
            return false;
        }
        if(monster->HP<=0)
        {
            monster->HP=0;
            printf("恭喜你杀死了怪兽!\n");
            return true;
        }
        printf("当前怪物的剩余血量:%d\n",monster->HP);
        printf("当前你的剩余血量:%d\n",player->HP);   
    }
    
}


int main()
{
    srand(time(NULL));

    struct Player player;
    InitPlayer(&player);

    struct DynamicArray monsters;
    InitMonsters(&monsters);

    struct DynamicArray treasures;
    InitTreasures(&treasures);

    printf("欢迎来到魔塔世界!\n");
    while(1)
    {
        // system("clear");
        printf("你当前所在的位置是:<%d,%d>\n",player.x,player.y);
        for(int i=0;i<monsters.len;i++)
        {
            struct Monster *monster=(struct Monster *)monsters.dp[i];
            if(monster->HP>0 && monster->x==player.x && monster->y==player.y)
            {
                if(Battle(&player,monster)==false)
                {
                    printf("您被击败了，游戏结束!\n");
                    break;
                }
            }
        }

        for(int i=0;i<monsters.len;i++)
        {
            struct Treasure *treasure=(struct Treasure *)treasures.dp[i];
            if(treasure->value!=0 && treasure->x==player.x && treasure->y==player.y)
            {
                printf("您获得了%s,价值是%d\n",treasure->name.string,treasure->value);
                treasure->value=0;
            }
        }

        printf("请按'w''a''s''d'进行移动:");
        char move=0;
        scanf("%c",&move);
        switch(move)
        {
            case 'w':
                MakeMove(&player,0,1);
                break;
            case 'a':
                MakeMove(&player,-1,0);
                break;
            case 's':
                MakeMove(&player,0,-1);
                break;
            case 'd':
                MakeMove(&player,1,0);
                break;
            default:
                break;
        }
    }

    for(int i=0;i<monsters.len;i++)
    {
        free((struct Monster*)monsters.dp[i]);
    }
    free(monsters.dp);

    for(int i=0;i<treasures.len;i++)
    {
        free((struct Treasure*)treasures.dp[i]);
    }
    free(treasures.dp);
    
    return 0;
}

